/*Slide 41 in  Introduction to Parallel I/O
 * Best practices slides 50-52
 *
 * Jumpshot and MPE tools
 * http://www.mcs.anl.gov/perfvis
 TAU
 * http://www.cs.uoregon.edu/research/tau/home.php
 Intel Trace Analyzer and Collector (formerly Pallas Vampir)
 * http://www.intel.com/cd/software/products/asmo-na/eng/cluster/tanalyzer/index.htm
 Paradyn
 * http://www.cs.wisc.edu/~paradyn
 Pablo
 * http://www.renci.org/software/
 Many other vendor tools exist
 * e.g., xmpi (SGI and HP)
 *
 * Reads mmapped file
 *
 * */
#include <stdlib.h>
#include <stdio.h>
#include "mpi.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "mpi_helper.h"
#include "fileparser.cpp"

#define FILEPATH "./dcsc_mat.bin"

using namespace std;


int main(int argc, char* argv[]) {
	int np, myid;
	MPI_Offset offset;
	MPI_File myfile; /* Shared file */
	MPI_Status status; /* Status returned from read */
	struct stat sb;

	/* Initialize MPI */
	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &myid);
	MPI_Comm_size(MPI_COMM_WORLD, &np);

	int fd = open(FILEPATH, O_RDONLY);

	if (fd == -1) {
		perror("Error opening file for reading");
		exit(EXIT_FAILURE);
	}

	if (fstat(fd, &sb) == -1) {
		perror("Error on fstat");
		exit(EXIT_FAILURE);
	}

	char * map = (char*) mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
	if (map == MAP_FAILED) {
		close(fd);
		perror("Error mmapping the file");
		exit(EXIT_FAILURE);
	}

	printf("filesize: %d", (int)sb.st_size);
	for (int i = 0; i < 20; i++) {
		cerr << "at: " << map[i] << endl;
		//printf("int at %s: %s\n", i,  map[i]);
	}
	/* Read the file int-by-int from the mmap
	 */
	int size = sb.st_size / sizeof(int);
	/*int *buf = (int*) malloc(sizeof(int) * 1001);
	for (int i = 1; i <= NUMINTS; ++i) {
		buf[i % 1001] = map[i];
	}
*/
	if (munmap(map, sb.st_size) == -1) {
		perror("Error un-mmapping the file");
	}

	close(fd);
	printf("finished\n ");

	MPI_Finalize();
	exit(0);
}

/*
 Get the size of the file
 MPI_File_get_size(myfile, &filesize);
 Calculate how many elements that is
 filesize = filesize / sizeof(char);
 Calculate how many elements each processor gets
 //bufsize = filesize/np;
 bufsize = filesize;
 Allocate the buffer to read to, one extra for terminating null char
 buf = (char *) malloc((bufsize + 1) * sizeof(char));
 Set the file view
 MPI_File_set_view(myfile, 0 * bufsize * sizeof(char), MPI_CHAR, MPI_BYTE,
 "native", MPI_INFO_NULL);
 Read from the file
 MPI_File_read(myfile, buf, bufsize, MPI_CHAR, &status);
 Find out how many elemyidnts were read

 MPI_Get_count(&status, MPI_BYTE, &nrchar);
 Set terminating null char in the string
 buf[nrchar] = (char) 0;
 printf("Process %2d read %d characters: ", myid, nrchar);
 printf("  %s\n", buf);
 */

